#pragma once

#ifndef Modifies_h
#define Modifies_h

#include <vector>
#include <map>
#include "Type.h"

class Modifies{

private:
	typedef	std::map<Type::Index::Line, Type::List::Var> LVarTableType;
	typedef std::map<Type::Index::Var, Type::Map::EntityLine> LineTableType;
	typedef	std::map<Type::Index::Proc, Type::List::Var> PVarTableType;
	typedef std::map<Type::Index::Var, Type::List::Proc> ProcTableType;

	LVarTableType modifiesLVarTable;
	LineTableType modifiesLineTable;
	PVarTableType modifiesPVarTable;
	ProcTableType modifiesProcTable;
	Type::Map::Bit modifiesLineBitMap;
	Type::Map::Bit modifiesProcBitMap;
	Type::Map::LineMatrix lastModifiedLVMatrix;
	Type::Map::LineMatrix nextModifiedLVMatrix;

	const static Type::Entity::Line allLineType = Type::Entity::ALL_LINE_ENTITY;
public:
	Modifies(void);
	~Modifies(void);
	void clear();

	// set modifies relationship for the given line, entity, and variable, returns status of operation
	bool setLineModifies(Type::Index::Line, Type::Entity::Line, Type::Index::Var);
	// set modifies relationship for the given proc and variable, returns status of operation
	bool setProcModifies(Type::Index::Proc, Type::Index::Var);
	// set the bitmap (square matrix) for line uses relationship, , returns status of operation
	bool setLineModifiesBitMap(Type::Map::Bit&);
	// set the bitmap (square matrix) for proc uses relationship, , returns status of operation
	bool setProcModifiesBitMap(Type::Map::Bit&);
	// set the last modified line-variable matirx
	bool setLastModified(Type::Map::LineMatrix&);
	// set the next modified line-variable matrix
	bool setNextModified(Type::Map::LineMatrix&);

	// get all modified variables
	const Type::List::Var& getModifiedVars();
	// get the variable modified by the given line
	const Type::List::Var& getModifiedVarsByLine(Type::Index::Line);
	// get the variable modified by the given proc
	const Type::List::Var& getModifiedVarsByProc(Type::Index::Proc);

	// get the list of lines that modifies the given variable
	const Type::List::Line& getLinesModify(Type::Index::Var);
	// get the list of lines with given entity that modifies the given variable
	const Type::List::Line& getLinesModify(Type::Index::Var, Type::Entity::Line);
	// get the list of procs that modifies the given variable
	const Type::List::Proc& getProcsModify(Type::Index::Var);


	// get the last line where the given variable is modified before the given line
	Type::Index::Line getLastModified(Type::Index::Line, Type::Index::Var);

	// get the next line where the given variable is modified after the given line
	Type::Index::Line getNextModified(Type::Index::Line, Type::Index::Var);

	// check if the given line modifies the given variable 
	bool isLineModifies(Type::Index::Line, Type::Index::Var);
	// check if the given proc modifies the given variable 
	bool isProcModifies(Type::Index::Proc, Type::Index::Var);

	// check if the given variable exists in line
	bool isVarExistsInLine(Type::Index::Var);
	// check if the given line exists in var
	bool isLineExistsInVar(Type::Index::Line);
	// check if the given variable exists in proc
	bool isVarExistsInProc(Type::Index::Var);
	// check if the given line exists in var
	bool isProcExistsInVar(Type::Index::Proc);
};
#endif